/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package passwordcheckerOriginais;

/**
 *
 * @author Matheus
 */
public class PasswordChecker02{

    public void checkPassword(String pwd) {
        int nScore=0, nLength=0, nAlphaUC=0, nAlphaLC=0, nNumber=0, nSymbol=0, nMidChar=0, 
                nRequirements=0, nAlphasOnly=0, nNumbersOnly=0, nUnqChar=0, nRepChar=0,
                nConsecAlphaUC=0, nConsecAlphaLC=0, nConsecNumber=0, nConsecSymbol=0,
                nConsecCharType=0, nSeqAlpha=0, nSeqNumber=0, nSeqSymbol=0, nSeqChar=0,
                nReqChar=0, nMultConsecCharType=0;
        double nRepInc=0.0;
        int nMultRepChar=1, nMultConsecSymbol=1;
        int nMultMidChar=2, nMultRequirements=2, nMultConsecAlphaUC=2, nMultConsecAlphaLC=2,
                nMultConsecNumber=2;
        int nReqCharType=3, nMultAlphaUC=3, nMultAlphaLC=3, nMultSeqAlpha=3, nMultSeqNumber=3,
                nMultSeqSymbol=3;
        int nMultLength=4, nMultNumber=4;
        int nMultSymbol=6;
        int nTmpAlphaUC=-1, nTmpAlphaLC=-1, nTmpNumber=-1, nTmpSymbol=-1;
        String sAlphaUC="0", sAlphaLC="0", sNumber="0", sSymbol="0", sMidChar="0", sRequirements="0",
                sAlphasOnly="0", sNumbersOnly="0", sRepChar="0", sConsecAlphaUC="0", sConsecAlphaLC="0",
                sConsecNumber="0", sSeqAlpha="0", sSeqNumber="0", sSeqSymbol="0";
        String sAlphas = "abcdefghijlmnopqrstuvwxyz";
        String sNumerics = "01234567890";
        String sSymbols = ")!@#$%^&*()";
        String sComplexity = "Too Short";
        String sStandards = "Below";
        int nMinPwdLen = 8;

        if (pwd != null && !pwd.equals("")) {
            nScore = pwd.length() * nMultLength;
            nLength = pwd.length();
            char[] pwd2 = pwd.replaceAll("\\s+", "").toCharArray();
            int arrPwdLen = pwd2.length;
            
            for (int i = 0; i < arrPwdLen; i++) {
                if (Character.isLetter(pwd2[i]) && Character.isUpperCase(pwd2[i])) {
                    if (nTmpAlphaUC != -1) { if ((nTmpAlphaUC + 1) == i) { nConsecAlphaUC++; nConsecCharType++; } }
                    nTmpAlphaUC = i;
                    nAlphaUC++;
                }
                else if (Character.isLetter(pwd2[i]) && Character.isLowerCase(pwd2[i])) {
                    if (nTmpAlphaLC != -1) { if ((nTmpAlphaLC + 1) == i) { nConsecAlphaLC++; nConsecCharType++; } }
                    nTmpAlphaLC = i;
                    nAlphaLC++;
                }
                else if (Character.isDigit(pwd2[i])) {
                    if (i > 0 && i < (arrPwdLen - 1)) { nMidChar++; }
                        if (nTmpNumber != -1) { if ((nTmpNumber + 1) == i) { nConsecNumber++; nConsecCharType++; } }
                            nTmpNumber = i;
                            nNumber++;
                        }
                        else if (!Character.isDigit(pwd2[i]) && !Character.isLetter(pwd2[i]) && pwd2[i] != '_') {
                            if (i > 0 && i < (arrPwdLen - 1)) { nMidChar++; }
                            if (nTmpSymbol != -1) { if ((nTmpSymbol + 1) == i) { nConsecSymbol++; nConsecCharType++; } }
                            nTmpSymbol = i;
                            nSymbol++;
                        }

                        boolean bCharExists = false;
                        for (int b=0; b < arrPwdLen; b++) {
                            if (pwd2[i] == pwd2[b] && i != b) {
                                bCharExists = true;
                                nRepInc += Math.abs((double)arrPwdLen/(b-i));
                                }
                        }
                        if (bCharExists) {
                                nRepChar++;
                                nUnqChar = arrPwdLen-nRepChar;
                                nRepInc = (nUnqChar != 0) ? (int)Math.ceil(nRepInc/nUnqChar) : (int)Math.ceil(nRepInc);
                        }
                }

                for (int s=0; s < 22; s++) {
                        String sFwd = sAlphas.substring(s,s+3);
                        String sRev = new StringBuffer(sFwd).reverse().toString();
                        if (pwd.toLowerCase().indexOf(sFwd) != -1 || pwd.toLowerCase().indexOf(sRev) != -1) { nSeqAlpha++; nSeqChar++;}
                }

                for (int s=0; s < 8; s++) {
                        String sFwd = sNumerics.substring(s,s+3);
                        String sRev = new StringBuffer(sFwd).reverse().toString();
                        if (pwd.toLowerCase().indexOf(sFwd) != -1 || pwd.toLowerCase().indexOf(sRev) != -1) { nSeqNumber++; nSeqChar++;}
                }

                for (int s=0; s < 8; s++) {
                        String sFwd = sSymbols.substring(s,s+3);
                        String sRev = new StringBuffer(sFwd).reverse().toString();
                        if (pwd.toLowerCase().indexOf(sFwd) != -1 || pwd.toLowerCase().indexOf(sRev) != -1) { nSeqSymbol++; nSeqChar++;}
                }

                if (nAlphaUC > 0 && nAlphaUC < nLength) {
                        nScore = nScore + (nLength - nAlphaUC) * 2;
                        sAlphaUC = "+ " + (nLength - nAlphaUC) * 2;
                }
                if (nAlphaLC > 0 && nAlphaLC < nLength) {
                        nScore = nScore + (nLength - nAlphaLC) * 2;
                        sAlphaLC = "+ " + (nLength - nAlphaLC) * 2;
                }
                if (nNumber > 0 && nNumber < nLength) {
                        nScore = nScore + nNumber * nMultNumber;
                        sNumber = "+ " + nNumber * nMultNumber;
                }
                if (nSymbol > 0) {
                        nScore = nScore + nSymbol * nMultSymbol;
                        sSymbol = "+ " + nSymbol * nMultSymbol;
                }
                if (nMidChar > 0) {
                        nScore = nScore + nMidChar * nMultMidChar;
                        sMidChar = "+ " + nMidChar * nMultMidChar;
                }

                if ((nAlphaLC > 0 || nAlphaUC > 0) && nSymbol == 0 && nNumber == 0) {
                        nScore = nScore - nLength;
                        nAlphasOnly = nLength;
                        sAlphasOnly = "- " + nLength;
                }
                if (nAlphaLC == 0 && nAlphaUC == 0 && nSymbol == 0 && nNumber > 0) {
                        nScore = nScore - nLength;
                        nNumbersOnly = nLength;
                        sNumbersOnly = "- " + nLength;
                }
                if (nRepChar > 0) {
                        nScore = nScore - (int)nRepInc;
                        sRepChar = "- " + nRepInc;
                }
                if (nConsecAlphaUC > 0) {
                        nScore = nScore - nConsecAlphaUC * nMultConsecAlphaUC;
                        sConsecAlphaUC = "- " + nConsecAlphaUC * nMultConsecAlphaUC;
                }
                if (nConsecAlphaLC > 0) {
                        nScore = nScore - nConsecAlphaLC * nMultConsecAlphaLC;
                        sConsecAlphaLC = "- " + nConsecAlphaLC * nMultConsecAlphaLC;
                }
                if (nConsecNumber > 0) {
                        nScore = nScore - nConsecNumber * nMultConsecNumber;
                        sConsecNumber = "- " + nConsecNumber * nMultConsecNumber;
                }
                if (nSeqAlpha > 0) {
                        nScore = nScore - nSeqAlpha * nMultSeqAlpha;
                        sSeqAlpha = "- " + nSeqAlpha * nMultSeqAlpha;
                }
                if (nSeqNumber > 0) {
                        nScore = nScore - nSeqNumber * nMultSeqNumber;
                        sSeqNumber = "- " + nSeqNumber * nMultSeqNumber;
                }
                if (nSeqSymbol > 0) {
                        nScore = nScore - nSeqSymbol * nMultSeqSymbol;
                        sSeqSymbol = "- " + nSeqSymbol * nMultSeqSymbol;
                }

                int[] arrChars = { nLength, nAlphaUC, nAlphaLC, nNumber, nSymbol };
                String[] arrCharsIds = { "nLength", "nAlphaUC", "nAlphaLC", "nNumber", "nSymbol" };
                int arrCharsLen = arrChars.length;
                for (int c=0; c < arrCharsLen; c++) {
                        int minVal;
                        if (arrCharsIds[c].equals("nLength")) { minVal = nMinPwdLen - 1; } else { minVal = 0; }
                        if (arrChars[c] == (minVal + 1)) { nReqChar++; }
                        else if (arrChars[c] > (minVal + 1)) { nReqChar++; }
                }

                nRequirements = nReqChar;
                int nMinReqChars;
                if (pwd.length() >= nMinPwdLen) { nMinReqChars = 3; } else { nMinReqChars = 4; }
                if (nRequirements > nMinReqChars) {
                        nScore = nScore + nRequirements * 2;
                        sRequirements = "+ " + nRequirements * 2;
                }

                if (nScore > 100) { nScore = 100; } else if (nScore < 0) { nScore = 0; }
                if (nScore >= 0 && nScore < 20) { sComplexity = "Very Weak"; }
                else if (nScore >= 20 && nScore < 40) { sComplexity = "Weak"; }
                else if (nScore >= 40 && nScore < 60) { sComplexity = "Medium"; }
                else if (nScore >= 60 && nScore < 80) { sComplexity = "Strong"; }
                else if (nScore >= 80 && nScore <= 100) { sComplexity = "Very Strong"; }

                System.out.println("Strength score is: " + nScore + "%");
                System.out.println("Strength verdict: " + sComplexity);
        }
        else {
                System.out.println("Strength score is:" + nScore + "%");
                System.out.println("Strength verdict: " + sComplexity);
        }
    }
}
